package com.da.web.sys_file;

import cn.dev33.satoken.annotation.SaIgnore;
import com.da.common.Result;
import com.da.exception.MyException;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * @author da
 * @time 2023/12/19 下午 6:26
 * 文件上传接口
 */
@RestController
@RequestMapping("/api/file")
public class FileController {

    //    文件上传路径
    @Value("${fileSavePath}")
    private String saveFilePath;

    //    文件上传
    @PostMapping("/upload")
    public Result upload(@RequestParam("file") MultipartFile file) {
        String downUrl;
        try {
//        获取上传文件的名字
            String filename = file.getOriginalFilename();
            if (filename == null || filename.isEmpty()) {
                throw new MyException(500, "文件上传有误");
            }
//        获取存放文件的位置
            final Path rootPath = Paths.get(System.getProperty("user.dir") + File.separator + saveFilePath);
//        不存在就创建
            if (!Files.exists(rootPath)) {
                Files.createDirectory(rootPath);
            }
//        文件保存的位置
            final Path path = Paths.get(rootPath + File.separator + filename);
//        写入内容到指定位置
            file.transferTo(path);
//            生成下载链接
            downUrl = "/api/file/" + URLEncoder.encode(filename, StandardCharsets.UTF_8);
        } catch (IOException e) {
            throw new MyException(500, "文件上传错误: " + e.getMessage());
        }
        return Result.success(downUrl);
    }

    @SaIgnore
    @SuppressWarnings("all")
    @GetMapping("/{fileName}")
    public void download(@PathVariable String fileName, HttpServletResponse response) {
        final Path path = Paths.get(System.getProperty("user.dir") + File.separator + saveFilePath + File.separator + fileName);
//        设置响应头
        response.setContentType("application/octet-stream");
        WritableByteChannel writableByteChannel = null;
        FileChannel fileChannel = null;
        try {
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
//        获取输出流
            writableByteChannel = Channels.newChannel(response.getOutputStream());
//        读取文件流通道
            fileChannel = new FileInputStream(path.toFile()).getChannel();
//        写入数据到通道
            fileChannel.transferTo(0, fileChannel.size(), writableByteChannel);
        } catch (IOException e) {
            throw new MyException(500, e.getMessage());
        } finally {
            try {
                if (fileChannel != null) {
                    fileChannel.close();
                }
            } catch (IOException e) {
                throw new MyException(500, e.getMessage());
            }
            try {
                if (writableByteChannel != null) {
                    writableByteChannel.close();
                }
            } catch (IOException e) {
                throw new MyException(500, e.getMessage());
            }
        }
    }
}
